package com.llongwill.slg.gateway.config;

import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.llongwill.slg.auth.appservice.IUserRoleQueryAppService;
import com.llongwill.slg.auth.entity.UserRoleDTO;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 权限加载接口实现类
 *
 * @author xiangff
 */
@Component
@Slf4j
@RequiredArgsConstructor(onConstructor_={@Autowired})
public class StpInterfaceImpl implements StpInterface {

    public static final String PERMS = "PERMS";
    public static final String ROLES = "ROLES";

    private final IUserRoleQueryAppService userRoleQueryAppService;

    private final ThreadPollConfig threadPollConfig;

    /**
     * 获取权限列表
     *
     * @param loginId
     * @param loginType
     * @return
     */
    @SneakyThrows
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        Object res = StpUtil.getTokenSession().get(PERMS);

        if (res == null) {
            CompletableFuture<List<String>> roleFuture = CompletableFuture.supplyAsync(() -> {

                // 返回此 loginId 拥有的权限列表
                List<String> permissonCodes = userRoleQueryAppService.getUserPermissonCodes(String.valueOf(loginId));
                String tokenValue = StpUtil.getTokenValueByLoginId(loginId);
                //保存用户权限
                StpUtil.getTokenSessionByToken(tokenValue).set(PERMS, permissonCodes);

                return permissonCodes;
            }, threadPollConfig.USER_ROLE_PERM_THREAD_POOL);

            return roleFuture.get();

        }
        return (List<String>) res;
    }

    /**
     * 获取角色
     *
     * @param loginId   登录id
     * @param loginType 登录类型
     * @return 角色列表
     */
    @SneakyThrows
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        Object res = StpUtil.getTokenSession().get(ROLES);

        if (res == null) {
            CompletableFuture<List<String>> roleFuture = CompletableFuture.supplyAsync(() -> {

                // 返回此 loginId 拥有的角色列表
                List<UserRoleDTO> roles = userRoleQueryAppService.getUserRoles(String.valueOf(loginId));
                String tokenValue = StpUtil.getTokenValueByLoginId(loginId);
                //保存用户角色
                List<String> roleCodeList = roles.stream().map(UserRoleDTO::getRoleCode)
                        .filter(StringUtils::isNotEmpty)
                        .collect(Collectors.toList());
                StpUtil.getTokenSessionByToken(tokenValue).set(ROLES, roleCodeList);

                return roleCodeList;
            }, threadPollConfig.USER_ROLE_PERM_THREAD_POOL);

            return roleFuture.get();

        }
        return (List<String>) res;
    }


}
